﻿using System;
using System.Threading;
using Fortune.Log;
using Fortune.POCO;
using Newtonsoft.Json;
using WebSocketSharp;
using WebSocketSharp.Server;
using Debug = UnityEngine.Debug;

namespace Fortune.API
{
    /// <summary>
    /// 抽象API，封装了WebSocket的一些通用逻辑
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class AbstractApi<T> : WebSocketBehavior where T : class
    {
        private static readonly FortuneLogger logger = FortuneLogger.newInstance(typeof(AbstractApi<>));
        
        /// <summary>
        /// 实际处理逻辑类，需要实现
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        protected abstract object handle(T param);
        
        /// <summary>
        /// 参数后处理
        /// </summary>
        /// <param name="param"></param>
        protected virtual void afterHandle(object param)
        {
        }
        
        /// <summary>
        /// 参数预处理
        /// </summary>
        protected virtual void beforeHandle()
        {
        }
        
        protected override void OnClose(CloseEventArgs e)
        {
            logger.warning($"{ID}-断开连接");
        }

        protected override void OnError(ErrorEventArgs e)
        {
            logger.error($"{ID}-发生异常", e.Exception);
        }

        protected override void OnMessage(MessageEventArgs e)
        {
            beforeHandle();
            // var rawData = e.Data;
            // T param;
            // // 不为空且当前类参数不为string
            // if (!string.IsNullOrWhiteSpace(rawData) && typeof(T) != typeof(string))
            // {
            //     param = JsonConvert.DeserializeObject<T>(rawData);
            // }
            // else
            // {
            //     param = (T)(object)rawData;
            // }
            
            try
            {
                Debug.Log($"[{Thread.CurrentThread.Name}]-{ID}-接到消息-{e.Data}");
                object invokeResult = handle(parseParam(e.Data));
                Send(JsonConvert.SerializeObject(Result<object>.success(ID, invokeResult)));
            }
            catch (Exception exception)
            {
                logger.error("接口异常", exception);
                Send(JsonConvert.SerializeObject(Result<object>.failed(ID, "fail")));
            }
            afterHandle(default);
        }

        protected virtual T parseParam(string paramString)
        {
            if (typeof(T) == typeof(string))
            {
                logger.debug("String类型参数，不作解析");
                return paramString as T;
            }

            if (typeof(T) == typeof(object))
            {
                logger.debug("Object类型参数，不作解析");
                return paramString as T;
            }
            try
            {
                return JsonConvert.DeserializeObject<T>(paramString);
            }
            catch (Exception e)
            {
                logger.error($"参数解析失败: {paramString}", e);
            }

            return default;
        }

        protected override void OnOpen()
        {
            logger.info($"{ID}-打开连接");
        }
    }
}